home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyc (Python 2.6)
-
- '''Python sys.excepthook hook to generate apport crash dumps.
-
- See https://wiki.ubuntu.com/AutomatedProblemReports for details.
-
- Copyright (c) 2006 Canonical Ltd.
- Authors: Robert Collins <robert@ubuntu.com>
- Martin Pitt <martin.pitt@ubuntu.com>
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2 of the License, or (at your
- option) any later version. See http://www.gnu.org/copyleft/gpl.html for
- the full text of the license.
- '''
- import os
- import sys
-
- def apport_excepthook(exc_type, exc_obj, exc_tb):
- '''Catch an uncaught exception and make a traceback.'''
-
- try:
- if exc_type in (KeyboardInterrupt,):
- return None
- packaging = impl
- import apport.packaging_impl
- if not packaging.enabled():
- return None
- StringIO = StringIO
- import cStringIO
- import re
- import tempfile
- import traceback
- likely_packaged = likely_packaged
- import apport.fileutils
-
- try:
- binary = os.path.realpath(os.path.join(os.getcwdu(), sys.argv[0]))
- except (TypeError, AttributeError, IndexError):
- packaging.enabled()
- packaging.enabled()
- exc_type in (KeyboardInterrupt,)
-
- try:
- binary = os.readlink('/proc/%i/exe' % os.getpid())
- except OSError:
- return None
-
-
- None<EXCEPTION MATCH>OSError
-
- if not os.access(binary, os.X_OK) or not os.path.isfile(binary):
- return None
- if not likely_packaged(binary):
- return None
- import apport.report as apport
- pr = apport.report.Report()
- tb_file = StringIO()
- traceback.print_exception(exc_type, exc_obj, exc_tb, file = tb_file)
- pr['Traceback'] = tb_file.getvalue().strip()
- pr.add_proc_info()
- pr.add_user_info()
- pr['ExecutablePath'] = binary
- pr['PythonArgs'] = '%r' % sys.argv
- if pr.check_ignored():
- return None
- mangled_program = re.sub('/', '_', binary)
- user = os.getuid()
- pr_filename = '/var/crash/%s.%i.crash' % (mangled_program, user)
- if os.path.exists(pr_filename):
- if apport.fileutils.seen_report(pr_filename):
- os.unlink(pr_filename)
- else:
- return None
- apport.fileutils.seen_report(pr_filename)
- report_file = os.fdopen(os.open(pr_filename, os.O_WRONLY | os.O_CREAT | os.O_EXCL), 'w')
- os.chmod(pr_filename, 384)
-
- try:
- pr.write(report_file)
- finally:
- report_file.close()
-
- finally:
- if sys:
- sys.__excepthook__(exc_type, exc_obj, exc_tb)
-
-
-
-
- def install():
- '''Install the python apport hook.'''
- sys.excepthook = apport_excepthook
-
- if __name__ == '__main__':
- import unittest
- import tempfile
- import subprocess
- import os.path as os
- import stat
- import apport.fileutils as apport
- import problem_report
-
- class _PythonHookTest(unittest.TestCase):
-
- def test_env(self):
- '''Check the test environment.'''
- self.assertEqual(apport.fileutils.get_all_reports(), [], 'No crash reports already present')
-
-
- def _test_crash(self, extracode = '', scriptname = None):
- '''Create a test crash.'''
- if scriptname:
- script = scriptname
- fd = os.open(scriptname, os.O_CREAT | os.O_WRONLY)
- else:
- (fd, script) = tempfile.mkstemp(dir = apport.fileutils.report_dir)
-
- try:
- os.write(fd, "#!/usr/bin/python\ndef func(x):\n raise Exception, 'This should happen.'\n\n%s\nfunc(42)\n" % extracode)
- os.close(fd)
- os.chmod(script, 493)
- p = subprocess.Popen([
- script,
- 'testarg1',
- 'testarg2'], stdout = subprocess.PIPE, stderr = subprocess.PIPE)
- err = p.communicate()[1]
- self.assertEqual(p.returncode, 1, 'crashing test python program exits with failure code')
- self.assert_('Exception: This should happen.' in err)
- self.failIf('OSError' in err, err)
- finally:
- os.unlink(script)
-
- return script
-
-
- def test_general(self):
- '''general operation of the Python crash hook.'''
- script = self._test_crash()
- reports = apport.fileutils.get_new_reports()
- pr = None
-
- try:
- self.assertEqual(len(reports), 1, 'crashed Python program produced a report')
- self.assertEqual(stat.S_IMODE(os.stat(reports[0]).st_mode), 384, 'report has correct permissions')
- pr = problem_report.ProblemReport()
- pr.load(open(reports[0]))
- finally:
- for r in reports:
- os.unlink(r)
-
-
- expected_keys = [
- 'InterpreterPath',
- 'PythonArgs',
- 'Traceback',
- 'ProblemType',
- 'ProcEnviron',
- 'ProcStatus',
- 'ProcCmdline',
- 'Date',
- 'ExecutablePath',
- 'ProcMaps',
- 'UserGroups']
- self.assert_(set(expected_keys).issubset(set(pr.keys())), 'report has necessary fields')
- self.assert_('bin/python' in pr['InterpreterPath'])
- self.assertEqual(pr['ExecutablePath'], script)
- self.assertEqual(pr['PythonArgs'], "['%s', 'testarg1', 'testarg2']" % script)
- self.assert_(pr['Traceback'].startswith('Traceback'))
- self.assert_("func\n raise Exception, 'This should happen." in pr['Traceback'])
-
-
- def test_existing(self):
- '''Python crash hook overwrites seen existing files.'''
- script = self._test_crash()
- to_del = set()
-
- try:
- reports = apport.fileutils.get_new_reports()
- to_del.update(reports)
- self.assertEqual(len(reports), 1, 'crashed Python program produced a report')
- self.assertEqual(stat.S_IMODE(os.stat(reports[0]).st_mode), 384, 'report has correct permissions')
- apport.fileutils.mark_report_seen(reports[0])
- reports = apport.fileutils.get_new_reports()
- to_del.update(reports)
- self.assertEqual(len(reports), 0)
- script = self._test_crash(scriptname = script)
- reports = apport.fileutils.get_new_reports()
- to_del.update(reports)
- self.assertEqual(len(reports), 1)
- script = self._test_crash(scriptname = script)
- reports = apport.fileutils.get_new_reports()
- self.assertEqual(len(reports), 1)
- to_del.update(reports)
- finally:
- for r in to_del:
- os.unlink(r)
-
-
-
-
- def test_no_argv(self):
- '''with zapped sys.argv.'''
- self._test_crash('import sys\nsys.argv = None')
- reports = apport.fileutils.get_new_reports()
- pr = None
-
- try:
- self.assertEqual(len(reports), 1, 'crashed Python program produced a report')
- self.assertEqual(stat.S_IMODE(os.stat(reports[0]).st_mode), 384, 'report has correct permissions')
- pr = problem_report.ProblemReport()
- pr.load(open(reports[0]))
- finally:
- for r in reports:
- os.unlink(r)
-
-
- expected_keys = [
- 'InterpreterPath',
- 'Traceback',
- 'ProblemType',
- 'ProcEnviron',
- 'ProcStatus',
- 'ProcCmdline',
- 'Date',
- 'ExecutablePath',
- 'ProcMaps',
- 'UserGroups']
- self.assert_(set(expected_keys).issubset(set(pr.keys())), 'report has necessary fields')
- self.assert_('bin/python' in pr['InterpreterPath'])
- self.assert_(pr['Traceback'].startswith('Traceback'))
-
-
- def _assert_no_reports(self):
- '''Assert that there are no crash reports.'''
- reports = apport.fileutils.get_new_reports()
-
- try:
- self.assertEqual(len(reports), 0, 'no crash reports present (cwd: %s)' % os.getcwd())
- finally:
- for r in reports:
- pass
-
-
-
-
- def test_interactive(self):
- '''interactive Python sessions never generate a report.'''
- orig_cwd = os.getcwd()
-
- try:
- for d in ('/tmp', '/usr/local', '/usr'):
- os.chdir(d)
- p = subprocess.Popen([
- 'python'], stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
- (out, err) = p.communicate('raise ValueError')
- if not p.returncode != 0:
- raise AssertionError
- if not out == '':
- raise AssertionError
- if not 'ValueError' in err:
- raise AssertionError
- self._assert_no_reports()
- finally:
- os.chdir(orig_cwd)
-
-
-
- def test_ignoring(self):
- '''the Python crash hook respects the ignore list.'''
- (fd, script) = tempfile.mkstemp(dir = apport.fileutils.report_dir)
- ifpath = os.path.expanduser(apport.report._ignore_file)
- orig_ignore_file = None
-
- try:
- os.write(fd, "#!/usr/bin/python\ndef func(x):\n raise Exception, 'This should happen.'\n\nfunc(42)\n")
- os.close(fd)
- os.chmod(script, 493)
- if os.path.exists(ifpath):
- orig_ignore_file = ifpath + '.apporttest'
- os.rename(ifpath, orig_ignore_file)
-
- r = apport.report.Report()
- r['ExecutablePath'] = script
- r.mark_ignore()
- r = None
- p = subprocess.Popen([
- script,
- 'testarg1',
- 'testarg2'], stdout = subprocess.PIPE, stderr = subprocess.PIPE)
- err = p.communicate()[1]
- self.assertEqual(p.returncode, 1, 'crashing test python program exits with failure code')
- self.assert_('Exception: This should happen.' in err)
- finally:
- os.unlink(script)
- if os.path.exists(ifpath):
- os.unlink(ifpath)
-
- if orig_ignore_file:
- os.rename(orig_ignore_file, ifpath)
-
-
- reports = apport.fileutils.get_new_reports()
- pr = None
-
- try:
- self.assertEqual(len(reports), 0)
- finally:
- for r in reports:
- os.unlink(r)
-
-
-
-
- unittest.main()
-
-